from django.shortcuts import render
from django.views import View
from jqexception.jqexecption import (
    jq_try,
    UnknowErr,
    RaffleBusyErr,
    RightErr,
    NullErr,
    ReqMethodErr,
    ValueErr,
    BalanceInsufficientErr,
)

from django.core.paginator import Paginator
from rest_framework.parsers import JSONParser
from django.http import JsonResponse, HttpResponse

from jqgame.basegame import GameType
from typing import Any
from juqiadmin.auth import login_auth, JuqiUser
from django.db import transaction
from django.core.handlers.wsgi import WSGIRequest
from uuid import uuid4
from fuliwu.models import FuliwuGame, FuliwuGood, FuliwuRecoder,FuliEnroll
from .ser import FuliwuSer,FuliwuGoodSer,FuliwuRecoderSer,FuliwuFuliEnrollSer,XcxFuliwuFuliEnrollSer,Fuliwuserializer
from rest_framework import status
from wxuser.models import Users
from juqiadmin.models import Finance
from warehouse.models import GoodLevel,GoodLevelGameType,JuqiGood
import datetime
from jqpackage.models import UserPackageGoods
from juqiadmin.models import (
    Finance,
    get_game_finance,
    get_wxuser_finance,
    update_finnce_profit,
)
# Create your views here.

#获取,上架,创建,删除池子
class Game(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):

        limit = int(request.GET.get("limit", 10))
        curPage = int(request.GET.get("page", 1))
        state = request.GET.get("state", None)
        game_name = request.GET.get("name", None)
        draw = request.GET.get("draw", None)

        _game = FuliwuGame.objects.filter(deleted=False)
        if state != None:
            _game = _game.filter(state=state)

        if game_name != None:
            _game = _game.filter(name=game_name)

        if draw != None:
            _game = _game.filter(draw=draw)

        _game = _game.order_by("-id")

        pages = Paginator(_game, limit)
        paged = pages.page(curPage)

        game_data = FuliwuSer(paged, many=True).data

        res = {
            "code": 0,
            "data": game_data,
            "data_count": pages.count,
            "page_count": pages.num_pages,
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

    @login_auth
    @transaction.atomic
    def post(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game: dict = JSONParser().parse(request)

        print(game)

        game_s = Fuliwuserializer(data=game)

        if game_s.is_valid(raise_exception=True) == True:
            FuliwuGame.objects.create(**game)
        # game_s = game_s.save()
        #game_ = FuliwuSer(game_s, many=False).data
        return JsonResponse(game,status=status.HTTP_201_CREATED)
    
    @login_auth
    def put(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game: dict = JSONParser().parse(request)

        _game = FuliwuGame.objects.filter(uuid=game.pop('uuid')).first()
        if _game.state == 0:
            _game.state = 1
            res = {'code':0,'msg':'上架成功'}
        else:
            _game.state = 0
            res = {'code':0,'msg':'下架成功'}
        
        _game.save()

        return JsonResponse(res, status=status.HTTP_201_CREATED)
    
    @login_auth
    def delete(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game: dict = JSONParser().parse(request)
        game_uuid = game.pop("uuid")
        FuliwuGame.objects.filter(uuid=game_uuid).update(deleted=True)
        FuliwuGood.objects.filter(game_uuid=game_uuid).update(deleted=True)
        FuliwuRecoder.objects.filter(game_uuid=game_uuid).update(deleted=True)
        FuliEnroll.objects.filter(game_uuid=game_uuid).update(deleted=True)
        res = {'code':0,'msg':'删除成功'}
        return JsonResponse(res, status=status.HTTP_200_OK)
#获取福利屋池子详情
#修改福利屋池子
class GameDetail(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game_uuid = request.GET.get("uuid", None)

        _game = FuliwuGame.objects.filter(deleted=False).filter(uuid=game_uuid).first()

        game_data = FuliwuSer(_game, many=False).data

        res = {
            "code": 0,
            "data": game_data,
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

    @login_auth
    def put(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game: dict = JSONParser().parse(request)
        game_uuid = game.pop('uuid')

        FuliwuGame.objects.filter(uuid=game_uuid).update(**game)
        res = {
            "code": 0,
            "msg":'修改成功'
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)



#获取池子下的赏品
#删除赏品
#创建赏品
class GameGood(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        # u = kwargs["user_info"]
        # if u.type != "admin":
        #     raise RightErr
        
        game_uuid = request.GET.get("uuid")
        
        goods = FuliwuGood.objects.filter(game_uuid=game_uuid).filter(deleted=False)
        
        res = {'code':0,'data':FuliwuGoodSer(goods,many=True).data}
        return JsonResponse(res, status=status.HTTP_200_OK)

    @login_auth
    def delete(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        game: dict = JSONParser().parse(request)
        fuliwu_good = FuliwuGood.objects.filter(uuid=game.pop("uuid")).first()
        if not fuliwu_good:
            res = {'code':-1,"msg":"传参有误,赏品不存在"}
            return JsonResponse(res, status=status.HTTP_200_OK)
        fuliwu_good.deleted = True
        fuliwu_good.save()
        FuliwuRecoder.objects.filter(good_uuid=fuliwu_good.good_uuid).update(deleted=True)
        res = {'code':0,"msg":"删除赏品成功"}
        return JsonResponse(res, status=status.HTTP_200_OK)

    @login_auth
    @transaction.atomic
    def post(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr

        game: dict = JSONParser().parse(request)

        game_uuid = game.pop('game_uuid')
        _game = FuliwuGame.objects.filter(uuid=game_uuid).first()
        if not _game:
            res = {'code':-1,"msg":"池子不存在"}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)
        
        level_uuid = game.pop("level_uuid")
        _level = GoodLevel.objects.filter(uuid=level_uuid).first()
        if not _level:
            res = {'code':-1,"msg":"赏品等级不存在"}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        price = game.pop("price")
        juqi_good = JuqiGood.objects.create(
            name=game.pop("name"),
            display_url = game.pop("display_url"),
            price = price,
            recovery_price = game.pop("recovery_price"),
            game_type = "福利屋",
            level_title = _level.title
        )

        count = game.pop("count")
        FuliwuGood.objects.create(
            game_uuid = _game.uuid,
            good_uuid = juqi_good.uuid,
            level_uuid = level_uuid,
            count = count,
            rf_count = count,
            price = price
        )

        #生成中奖记录
        for num in range(0,count):
            FuliwuRecoder.objects.create(
                game_uuid=game_uuid,
                good_uuid=juqi_good.uuid,
            )

        res = {
            "code": 0,
            "msg":'创建成功'
        }
        return JsonResponse(res, status=status.HTTP_201_CREATED)


#单个赏品详情
#修改赏品
class GameGoodDetail(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        
        uuid = request.GET.get("uuid")
        
        goods = FuliwuGood.objects.filter(uuid=uuid).first()
        data = FuliwuGoodSer(goods,many=False).data
        data['name'] = data['good']['name']
        data['display_url'] = data['good']['display_url']
        data['price'] = data['good']['price']/100
        data['recovery_price'] = data['good']['recovery_price']/100
        
        res = {'code':0,'data':data}
        return JsonResponse(res, status=status.HTTP_200_OK)

    
    @login_auth
    @transaction.atomic
    def put(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        
        good: dict = JSONParser().parse(request)
        uuid = good.pop('uuid')
        
        goods = FuliwuGood.objects.filter(uuid=uuid).first()
        if not goods:
            raise UnknowErr
        

        
        _juqigood = JuqiGood.objects.filter(uuid=goods.good_uuid).first()
        _juqigood.name = good.pop("name")
        _juqigood.price = good.pop("price")
        _juqigood.recovery_price = good.pop("recovery_price")
        _juqigood.display_url = good.pop("display_url")
        
        _level = GoodLevel.objects.filter(uuid=good.get("level_uuid")).first()
        if _juqigood.level_title != _level.title:
            _juqigood.level_title = _level.title
        _juqigood.save()

        res = {
            "code": 0,
            "msg":'修改成功'
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)


#小程序端用户报名
#获取报名人列表
class UserEnroll(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "wxuser":
            raise RightErr
        
        game_uuid = request.GET.get("game_uuid")
        _enroll = FuliEnroll.objects.filter(game_uuid=game_uuid).filter(deleted=False)
        data = XcxFuliwuFuliEnrollSer(_enroll,many=True).data
        res = {'code':0,'data':data}
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)
    
    @login_auth
    @transaction.atomic
    def post(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "wxuser":
            raise RightErr

        now = datetime.datetime.now()
        openid = u.openid
        user = Users.objects.filter(openid=openid).first()

        body: dict = JSONParser().parse(request)
        game_uuid = body.pop("game_uuid")
        
        _game = FuliwuGame.objects.filter(uuid=game_uuid).select_for_update().first()
        if not _game or _game.state == 0:
            res = {'code':-1,'msg':'池子不存在'}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)
        
        if now >= _game.open_time:
            res = {'code':-1,'msg':'已经截至报名'}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        if _game.draw == 1:
            res = {'code':-1,'msg':'池子已开奖'}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)
        

        
        if FuliEnroll.objects.filter(game_uuid=game_uuid).filter(user_uuid=user.uuid).select_for_update().exists():
            res = {'code':-1,'msg':'已经报过名了'}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        print(_game.start_time,_game.end_time)
        user_finance = Finance.objects.filter(user_uuid=user.uuid).filter(createdAt__range=(_game.start_time,_game.end_time)).all()
        _income=0
        for item in user_finance:
            _income += item.all_raffle_income
        
        if _income >= _game.consumption_amount:
            FuliEnroll.objects.create(
                game_uuid=game_uuid,
                user_uuid=user.uuid
            )
            res = {'code':0,'msg':'报名成功'}
        else:
            cha_money = (_game.consumption_amount - _income) /100
            res = {'code':-1,'msg':f'对不起,您暂未达到参加条件还需消费{cha_money}赏币'}
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)



#管理员获取开奖记录
class GameRecoderCommit(View):
        
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        
        game_uuid = request.GET.get("game_uuid")
        _reocder = FuliwuRecoder.objects.filter(game_uuid=game_uuid).filter(deleted=False)
        
        res = {
            "code":0,
            "data":FuliwuRecoderSer(_reocder,many=True).data
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

    @login_auth
    @transaction.atomic
    def put(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        
        body: dict = JSONParser().parse(request)
        recoder_uuid = body.pop("recoder_uuid")
        enroll_uuid = body.pop("enroll_uuid")
        _recoder = FuliwuRecoder.objects.filter(uuid=recoder_uuid).first()
        if not _recoder:
            res = {"code":-1,"msg":"记录不存在"}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        if _recoder.state == 1:
            res = {"code":-1,"msg":"已开奖不可更改"}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)
        _user = FuliEnroll.objects.filter(uuid=enroll_uuid).first()
        if not _user:
            res = {"code":-1,"msg":"报名记录不存在"}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        #判断是否已存在用户 进行替换
        if _recoder.user_uuid:
            FuliEnroll.objects.filter(user_uuid=_recoder.user_uuid).update(state=0)
        _recoder.user_uuid = _user.user_uuid
        _user.state = 1
        _user.save()
        _recoder.save()
        res = {
            "code":0,
            "msg":"修改成功"
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

#获取报名人
class GameUserEnrollRecoder(View):

    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        
        game_uuid = request.GET.get("game_uuid")
        _reocder = FuliEnroll.objects.filter(game_uuid=game_uuid).filter(state=0)
        
        res = {
            "code":0,
            "data":FuliwuFuliEnrollSer(_reocder,many=True).data
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

class XcxUserRecoder(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "wxuser":
            raise RightErr
        
        game_uuid = request.GET.get("game_uuid")
        _game = FuliwuGame.objects.filter(uuid=game_uuid).first()
        print(_game.draw)
        if _game.draw == 0:
            res = {'code':-1,'msg':'暂未开奖'}
            return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)

        _reocder = FuliwuRecoder.objects.filter(game_uuid=game_uuid).filter(deleted=False)
        
        res = {
            "code":0,
            "data":FuliwuRecoderSer(_reocder,many=True).data
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)


class FuliwuOpen(View):
    @transaction.atomic
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        now_time = datetime.datetime.now()
        fuliwu_list = FuliwuGame.objects.filter(draw=0).filter(state=1).filter(deleted=False).filter(open_time__lte=now_time).all()
        #开奖的池子        
        page_create = []
        admin_cost = 0
        for item in fuliwu_list:
            #去中奖记录里拿出来数据
            recoder_ = FuliwuRecoder.objects.filter(game_uuid=item.uuid).filter(deleted=False).filter(state=0).all()
            #池子下的中奖记录
            for _v in recoder_:
                if _v.user_uuid == None:
                    _u = FuliEnroll.objects.filter(deleted=False).filter(game_uuid=item.uuid).filter(state=0).order_by("?").first()
                    if not _u:
                        break
                    else:
                        _u.state = 1
                        _u.save()
                        _v.user_uuid = _u.user_uuid

                        _good = JuqiGood.objects.filter(uuid = _v.good_uuid).first()
                        print(_good)
                        #计算赏柜总价值
                        user = Users.objects.filter(uuid=_u.user_uuid).select_for_update().first()
                        user.package_amount += _good.recovery_price
                        user.save()
                        #统计盈亏
                        user_finance =  get_wxuser_finance(
                                        user_uuid=_u.user_uuid,
                                        gameType=GameType.fuliwu,
                                        game_uuid=item.uuid,
                                    )
                        user_finance.all_raffle_cost += _good.recovery_price
                        user_finance.save()
                        admin_cost += _good.recovery_price

                        info = {
                            "user_uuid": _u.user_uuid,
                            "good_uuid": _good.uuid,
                            "good_level_title":_good.level_title,
                            "game_uuid": item.uuid,
                            "deleted": False,
                            "order_uuid":uuid4(),
                            "game_type": GameType.fuliwu.value
                        }
                        page_create.append(UserPackageGoods(**info))
                        _v.state = 1
                        _v.save()
                #确定好的人开奖
                else:
                    _good = JuqiGood.objects.filter(uuid = _v.good_uuid).first()
                    #计算赏柜总价值
                    user = Users.objects.filter(uuid=_v.user_uuid).select_for_update().first()
                    user.package_amount += _good.recovery_price
                    user.save()

                    #统计盈亏
                    user_finance =  get_wxuser_finance(
                                    user_uuid=_v.user_uuid,
                                    gameType=GameType.fuliwu,
                                    game_uuid=item.uuid,
                                )
                    user_finance.all_raffle_cost += _good.recovery_price
                    user_finance.save()
                    admin_cost += _good.recovery_price
                    
                    info = {
                        "user_uuid": _v.user_uuid,
                        "good_uuid": _good.uuid,
                        "good_level_title":_good.level_title,
                        "game_uuid": item.uuid,
                        "deleted": False,
                        "order_uuid":uuid4(),
                        "game_type": GameType.fuliwu.value
                    }
                    page_create.append(UserPackageGoods(**info))
                    _v.state = 1
                    _v.save()
                
            item.draw = 1
            item.save()
        fuliwu_finance = get_game_finance(GameType.fuliwu)
        fuliwu_finance.all_raffle_cost += admin_cost
        fuliwu_finance.save()
        UserPackageGoods.objects.bulk_create(page_create)
        res = {
                "code":0
            }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)


class XcxGameDetail(View):
    @login_auth
    def get(self, request: WSGIRequest, *args: Any, **kwargs: Any):
        u = kwargs["user_info"]
        if u.type != "wxuser":
            raise RightErr
        
        openid = u.openid
        user = Users.objects.filter(openid=openid).first()
        if not user:
            raise UnknowErr

        game_uuid = request.GET.get("uuid", None)

        _game = FuliwuGame.objects.filter(deleted=False).filter(uuid=game_uuid).first()

        game_data = FuliwuSer(_game, many=False).data

        user_status = FuliEnroll.objects.filter(game_uuid=game_uuid).filter(user_uuid=user.uuid).exists()

        res = {
            "code": 0,
            "data": game_data,
            "user_status":user_status
        }
        return JsonResponse(res, status=(status.HTTP_200_OK), safe=False)